package com.woniu.utils;





import com.woniu.exception.token.TokenException;
import com.woniu.exception.token.TokenExceptionCode;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JwtUtil 类用于生成和解析 JSON Web Tokens (JWT)。
 * JWT 是一种用于在网络上传输信息的开放标准 (RFC 7519)，通常用于身份验证。
 */
public class JwtUtil {
    
    // 用于签署管理员身份的密钥
    public static final String adminSecret = "jlsdjflsjflkjsdlfsdkldfnklsdnflsdnlksdkf";
    
    // 用于签署用户身份的密钥
    public static final String userSecret = "jlsdjfksdninfghfdgnkjnsuihfjsammjiaakiakaakakk";

    // 用于签署站长身份的密钥
    public static final String stationBossSecret = "dashdashashfkjashfkjashfkjsahfkjsahfkjhas";

    // 用于签署员工身份的密钥
    public static final String employSecret = "voahvoiadhfohafhaskfhjashkjabkjaatkajstk";
    
    /**
     * 生成Token
     *
     * @param body   Token 的主体信息，以键值对的形式存储
     * @param time   Token 的有效期（秒）
     * @param secret 用于签署 Token 的密钥
     * @return 生成的 JWT
     */
    public static String createToken(Map<String, Object> body, Integer time, String secret) {
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        JwtBuilder jb = Jwts.builder();
        // 检查主体信息是否存在
        if (body == null || body.size() <= 0) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_NO_DETAIL);
        }
        // 设置 Token 的主体信息
        jb.setClaims(body);
        // 设置 Token 的过期时间
        if (time == null) {
            jb.setExpiration(new Date(System.currentTimeMillis() + 60 * 30 * 1000));
        } else {
            jb.setExpiration(new Date(System.currentTimeMillis() + time * 1000));
        }
        // 使用密钥签署 Token 并返回
        return jb.signWith(key).compact();
    }
    
    /**
     * 生成Token，默认有效期为30分钟
     *
     * @param body   Token 的主体信息，以键值对的形式存储
     * @param secret 用于签署 Token 的密钥
     * @return 生成的 JWT
     */
    public static String createToken(Map<String, Object> body, String secret) {
        return createToken(body, null, secret);
    }
    
    /**
     * 解析 Token
     *
     * @param token  要解析的 JWT
     * @param secret 用于验证 Token 的密钥
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseToken(String token, String secret) throws Exception {
        if (token == null) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_TOKEN_NULL);
        }
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    }
    
    /**
     * 生成用户端Token
     *
     * @param body 用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createUserToken(Map<String, Object> body) {
        return createToken(body, userSecret);
    }
    
    /**
     * 生成用户端Token
     *
     * @param body 可变参数，用于构建用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createUserToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_NULL_DETAIL);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, userSecret);
    }



    /**
     * 生成员工端Token
     *
     * @param body 员工身份信息
     * @return 生成的用户端 JWT
     */
    public static String createEmployToken(Map<String, Object> body) {
        return createToken(body, employSecret);
    }

    /**
     * 生成员工端Token
     *
     * @param body 可变参数，用于构建用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createEmployToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_NULL_DETAIL);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, employSecret);
    }


    /**
     * 生成站长端Token
     *
     * @param body 用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String stationBossToken(Map<String, Object> body) {
        return createToken(body, stationBossSecret);
    }

    /**
     * 生成站长端Token
     *
     * @param body 可变参数，用于构建用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createStationBossToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_NULL_DETAIL);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, stationBossSecret);
    }





    /**
     * 生成管理员端Token
     *
     * @param body 管理员身份信息
     * @return 生成的管理员端 JWT
     */
    public static String createAdminToken(Map<String, Object> body) {
        return createToken(body, adminSecret);
    }
    
    /**
     * 生成管理员端Token
     *
     * @param body 可变参数，用于构建管理员身份信息
     * @return 生成的管理员端 JWT<dependency>
     *     <groupId>com.alibaba.cloud</groupId>
     *     <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
     * </dependency>
     */
    public static String createAdminToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException(TokenExceptionCode.CK_TOKEN_INFO_NULL_DETAIL);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, adminSecret);
    }


    /**
     * 解析站长端Token
     *
     * @param token 要解析的站长端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseStationBossToken(String token) throws Exception {
        return parseToken(token, stationBossSecret);
    }


    /**
     * 解析员工端Token
     *
     * @param token 要解析的用户端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseEmployToken(String token) throws Exception {
        return parseToken(token, employSecret);
    }


    /**
     * 解析用户端Token
     *
     * @param token 要解析的用户端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseUserToken(String token) throws Exception {
        return parseToken(token, userSecret);
    }
    
    /**
     * 解析管理员端Token
     *
     * @param token 要解析的管理员端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseAdminToken(String token) throws Exception {
        return parseToken(token, adminSecret);
    }

    public static void main(String[] args) throws Exception {
//        System.out.println(createUserToken("userId", 1));
//        System.out.println(parseUserToken(createUserToken("userId", 1)));
//        Claims userId = parseUserToken((createUserToken("userId", 1)));
//        System.out.println(userId.get("userId"));
//        Claims claims = parseToken("eyJhbGciOiJIUzI1NiJ9.eyJ7YWNjb3VudElkPTEsIGFjY291bnRQYXNzPTEyMzQ1NiwgYWNjb3VudFBob25lPTE3NjEyMzA2NjY2LCBhY2NvdW50U3RhdGU9MCwgcm9sZT0zfSI6ODY0MDAsImV4cCI6MTcxNzQ5MzQwM30.fZ91O-c-3N2W3LBehVU6oSBRceOx_1MKuNTmaWSggao", stationBossSecret);
//        System.out.println(claims.get("accountId"));
        //System.out.println(createStationBossToken("accountId", 1));

//        Claims claims = parseToken("eyJhbGciOiJIUzI1NiJ9.eyJhY2NvdW50SWQiOjEsImFjY291bnRQYXNzIjoiMTIzNDU2IiwiYWNjb3VudFBob25lIjoiMTc2MTIzMDY2NjYiLCJhY2NvdW50U3RhdGUiOjAsInJvbGUiOjMsImV4cCI6MTcxNzU4NTM5NH0.30mBmf2SzdTB3uwSzgwws3rnnr7A4lMlJiY--EXoB7c", stationBossSecret);
//        System.out.println(claims);
//        System.out.println(claims.get("accountId"));
        parseStationBossToken("eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6eyJyYW5kb20iOiIxODAwNDMwNjgwODMyODcyNDQ4In0sImV4cCI6MTcxODA5Mjg5OX0.fnSXiR1bv1qHe8_Ey5f17NbzOorPYbS_e0oHK9Ii8fQ");
        System.out.println("________________");
        parseUserToken("eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6eyJyYW5kb20iOiIxODAwNDMwNjgwODMyODcyNDQ4In0sImV4cCI6MTcxODA5Mjg5OX0.fnSXiR1bv1qHe8_Ey5f17NbzOorPYbS_e0oHK9Ii8fQ");
    }
}
